﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SiGeSIB.Data.Security;
using SiGeSIB.GUI.Common;
using SiGeSIB.Services;
using SiGeSIB.Data.Common;

namespace SiGeSIB.GUI.Security
{
	public partial class FLogin : Form
    {
        #region Constructor
        public FLogin()
        {
            InitializeComponent();

			this.StartPosition = FormStartPosition.CenterScreen;

            _Manager = Manager.Instance;
            _ConfigMgr = ConfigurationManager.Instance;
            _Controller = new FormController(defaultStatusBar1);
            _Controller.AddErrorLabel("InvalidLogin", new Control[] { lblLogin, txtLogin });
            _Controller.AddErrorLabel("InvalidPassword", new Control[] { lblPassword, txtPassword });
			_Controller.AddErrorLabel("InvalidCredentials", new Control[] {lblLogin, lblPassword, txtLogin, txtPassword});
            
            _Controller.FieldsToLock = new List<object>()
                {
                    cboConnections,
                    txtLogin,
                    txtPassword,
                    btnConnections,
                    btnOk,
                    chkRemember
                };
        }
        #endregion

        #region Attributes
        private ConnectionSchemaCollection _Connections;
        private string _DefaultLogin;
        private ConfigurationManager _ConfigMgr;
        private Manager _Manager;
        private ConnectionSchema _SelectedConnection;
        private FormController _Controller; 
        #endregion

        #region Properties
        public ConnectionSchema SelectedConnection
        {
            get
            {
                return _SelectedConnection;
            }
            set
            {
                _SelectedConnection = value;

                cboConnections.SelectedValue = value;
            }
        } 
        #endregion

        #region Methods
        #region UIState
        private void _RefreshUIState()
        {
            bool isEnable = !_Controller.IsBusy;

            btnOk.Enabled = isEnable && cboConnections.SelectedValue != null;
        }
        #endregion

        #region Loading
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            _LoadData();
        }

        private void _LoadData()
        {
            if (!bwLoadData.IsBusy)
            {
                _Controller.EnableBusy();
                bwLoadData.RunWorkerAsync();
            }
        }

        private void bwLoadData_DoWork(object sender, DoWorkEventArgs e)
        {
            _Connections = _ConfigMgr.Connections;
            _DefaultLogin = _ConfigMgr.DefaultLogin;
        }

        private void bwLoadData_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (!IsDisposed)
            {
                if (e.Error == null)
                {
					if (!string.IsNullOrEmpty(_DefaultLogin))
					{
						txtLogin.Text = _DefaultLogin;
						chkRemember.Checked = true;
						txtPassword.Select();
					}
					else
						txtLogin.Select();

                    _FillConnectionsComboBox();
                    _Controller.DisableBusy();
                    _RefreshUIState();
                }
                else
                {
                    _Controller.DisableBusy();
                    MessageBox.Show(e.Error.Message);
                }
            }
        }

        private void _FillConnectionsComboBox()
        {
            if (_Connections != null)
            {
                List<KeyValuePair<string, ConnectionSchema>> connections = new List<KeyValuePair<string, ConnectionSchema>>();

                foreach (ConnectionSchema conn in _Connections)
                    connections.Add(new KeyValuePair<string, ConnectionSchema>(conn.ConnectionName, conn));

                cboConnections.DisplayMember = "Key";
                cboConnections.ValueMember = "Value";
                cboConnections.DataSource = connections;

                if (_Connections.SelectedSchema != null)
                    cboConnections.SelectedValue = _Connections.SelectedSchema;
            }
        }
        #endregion

        #region Event Handlers
        private void btnConnections_Click(object sender, EventArgs e)
        {
            FManageConnections frm = new FManageConnections(_Connections);
            this.Visible = false;
			frm.StartPosition = FormStartPosition.CenterParent;
            if (frm.ShowDialog() == DialogResult.OK)
            {
                _LoadData();
            }

            this.Visible = true;
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            _Login();
        }
        #endregion

        #region Login
        private void _Login()
        {
            _Controller.ClearErrors();
            if (!bwLogin.IsBusy)
            {
                _Controller.EnableBusy();
                _ConfigMgr.Connections.SelectedSchema = (ConnectionSchema)cboConnections.SelectedValue;
                bwLogin.RunWorkerAsync();
            }
        }

        private void _ValidateParameters()
        {
            if (string.IsNullOrEmpty(txtLogin.Text))
                throw new InvalidLoginException("InvalidLogin", "É necessário preencher o login para acessar o sistema.");
            if (string.IsNullOrEmpty(txtPassword.Text))
                throw new InvalidPasswordException("InvalidPassword", "É necessário preencher a senha para acessar o sistema.");
        }

        private void bwLogin_DoWork(object sender, DoWorkEventArgs e)
        {
            _ValidateParameters();

            _ConfigMgr.DefaultLogin = chkRemember.Checked ? txtLogin.Text : null;
            ISecurityServicesProvider secProv = _Manager.ServicesProvider.CreateSecurityServicesProvider();
            _Manager.LoggedUser = secProv.Login(txtLogin.Text, txtPassword.Text);
        }

        private void bwLogin_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (!IsDisposed)
            {
                if (e.Error == null)
                {
                    _Controller.DisableBusy();
                    this.DialogResult = DialogResult.OK;
                    this.Close();
                }
                else
                {
                    _Controller.DisableBusy();
                    _Controller.LoadError(e.Error);
                }
            }
        }
        #endregion
        #endregion
    }
}
